using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;

namespace MarkDownFileSplitter.Meilisearch
{
    public partial class FieldEditControl : UserControl
    {
        private IndexInfo indexInfo;

        public FieldEditControl()
        {
            InitializeComponent();
        }

        internal void UpdateIndex(IndexInfo indexInfo)
        {
            this.indexInfo = indexInfo;
            if (indexInfo != null)
            {
                this.labelIndexName.Text = $"索引字段：{indexInfo.IndexName}";
                LoadFields();
            }
        }

        private async void LoadFields()
        {
            if (indexInfo == null) return;

            try
            {
                listViewFields.Items.Clear();
                
                // 获取索引的设置信息
                var settings = await MeilisearchUploader.Instance.GetIndexSettings(indexInfo.IndexName);
                
                if (settings != null)
                {
                    // 获取可过滤字段
                    var filterableAttributes = settings["filterableAttributes"] as JArray ?? new JArray();
                    // 获取可排序字段
                    var sortableAttributes = settings["sortableAttributes"] as JArray ?? new JArray();
                    // 获取显示字段
                    var displayedAttributes = settings["displayedAttributes"] as JArray ?? new JArray();
                    
                    // 如果displayedAttributes为空或者包含"*"，则获取所有字段
                    if (displayedAttributes.Count == 0 || 
                        (displayedAttributes.Count == 1 && displayedAttributes[0].ToString() == "*"))
                    {
                        displayedAttributes = new JArray();
                        // 通过搜索获取一个文档来推断字段
                        var searchResult = await MeilisearchUploader.Instance.Search(indexInfo.IndexName, "", 1, 0, "");
                        var hits = searchResult["hits"] as JArray;
                        if (hits != null && hits.Count > 0)
                        {
                            var firstDoc = hits[0] as JObject;
                            if (firstDoc != null)
                            {
                                foreach (var prop in firstDoc.Properties())
                                {
                                    if (!prop.Name.StartsWith("_")) // 排除内部字段
                                    {
                                        displayedAttributes.Add(prop.Name);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // 如果没有文档，尝试从其他设置中获取字段信息
                            var allFields = new HashSet<string>();
                            
                            // 从filterableAttributes中获取字段
                            foreach (var field in filterableAttributes)
                            {
                                allFields.Add(field.ToString());
                            }
                            
                            // 从sortableAttributes中获取字段
                            foreach (var field in sortableAttributes)
                            {
                                allFields.Add(field.ToString());
                            }
                            
                            // 从searchableAttributes中获取字段
                            var searchableAttributes = settings["searchableAttributes"] as JArray ?? new JArray();
                            foreach (var field in searchableAttributes)
                            {
                                if (field.ToString() != "*")
                                {
                                    allFields.Add(field.ToString());
                                }
                            }
                            
                            // 添加到displayedAttributes
                            foreach (var field in allFields)
                            {
                                displayedAttributes.Add(field);
                            }
                        }
                    }
                    
                    // 显示字段信息
                    foreach (var field in displayedAttributes)
                    {
                        var fieldName = field.ToString();
                        var item = new ListViewItem(fieldName);
                        item.SubItems.Add("string"); // 默认类型
                        item.SubItems.Add(filterableAttributes.Any(x => x.ToString() == fieldName) ? "是" : "否");
                        item.SubItems.Add(sortableAttributes.Any(x => x.ToString() == fieldName) ? "是" : "否");
                        item.Tag = fieldName;
                        listViewFields.Items.Add(item);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载字段失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private async void toolStripMenuItemAddField_Click(object sender, EventArgs e)
        {
            if (indexInfo == null)
            {
                MessageBox.Show("请先选择一个索引", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            var dialog = new AddFieldDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    var fieldName = dialog.FieldName;
                    var fieldType = dialog.FieldType; // 新增
                    var isFilterable = dialog.IsFilterable;
                    var isSortable = dialog.IsSortable;

                    // 获取当前设置
                    var settings = await MeilisearchUploader.Instance.GetIndexSettings(indexInfo.IndexName);
                    var filterableAttributes = settings["filterableAttributes"] as JArray ?? new JArray();
                    var sortableAttributes = settings["sortableAttributes"] as JArray ?? new JArray();
                    var displayedAttributes = settings["displayedAttributes"] as JArray ?? new JArray();

                    // 处理displayedAttributes为["*"]的情况
                    if (displayedAttributes.Count == 1 && displayedAttributes[0].ToString() == "*")
                    {
                        // 获取当前所有实际字段
                        var actualFields = new JArray();
                        
                        // 通过搜索获取一个文档来推断字段
                        var searchResult = await MeilisearchUploader.Instance.Search(indexInfo.IndexName, "", 1, 0, "");
                        var hits = searchResult["hits"] as JArray;
                        if (hits != null && hits.Count > 0)
                        {
                            var firstDoc = hits[0] as JObject;
                            if (firstDoc != null)
                            {
                                foreach (var prop in firstDoc.Properties())
                                {
                                    if (!prop.Name.StartsWith("_")) // 排除内部字段
                                    {
                                        actualFields.Add(prop.Name);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // 如果没有文档，从其他设置中获取字段信息
                            var allFields = new HashSet<string>();
                            
                            foreach (var field in filterableAttributes)
                            {
                                allFields.Add(field.ToString());
                            }
                            
                            foreach (var field in sortableAttributes)
                            {
                                allFields.Add(field.ToString());
                            }
                            
                            var searchableAttributes = settings["searchableAttributes"] as JArray ?? new JArray();
                            foreach (var field in searchableAttributes)
                            {
                                if (field.ToString() != "*")
                                {
                                    allFields.Add(field.ToString());
                                }
                            }
                            
                            foreach (var field in allFields)
                            {
                                actualFields.Add(field);
                            }
                        }
                        
                        displayedAttributes = actualFields;
                    }

                    // 添加到显示字段
                    if (!displayedAttributes.Any(x => x.ToString() == fieldName))
                    {
                        displayedAttributes.Add(fieldName);
                    }

                    // 添加到可过滤字段
                    if (isFilterable && !filterableAttributes.Any(x => x.ToString() == fieldName))
                    {
                        filterableAttributes.Add(fieldName);
                    }

                    // 添加到可排序字段
                    if (isSortable && !sortableAttributes.Any(x => x.ToString() == fieldName))
                    {
                        sortableAttributes.Add(fieldName);
                    }

                    // 更新设置
                    var updateSettings = new JObject();
                    updateSettings["displayedAttributes"] = displayedAttributes;
                    updateSettings["filterableAttributes"] = filterableAttributes;
                    updateSettings["sortableAttributes"] = sortableAttributes;

                    await MeilisearchUploader.Instance.UpdateIndexSettings(indexInfo.IndexName, updateSettings);
                    
                    MessageBox.Show("字段添加成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    // 询问是否要为现有文档添加默认值
                    var result = MessageBox.Show(
                        $"字段 '{fieldName}' 已成功添加到索引设置中。\n\n是否要为现有文档添加该字段的默认值？\n\n将根据字段类型 '{fieldType}' 设置相应的默认值。",
                        "添加默认值",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question);
                        
                    if (result == DialogResult.Yes)
                    {
                        var defaultValue = GetDefaultValueByType(fieldType); // 新增方法
                        await AddFieldToExistingDocuments(fieldName, defaultValue);
                    }
                    
                    LoadFields(); // 刷新显示
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"添加字段失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private async void toolStripMenuItemDeleteField_Click(object sender, EventArgs e)
        {
            if (listViewFields.SelectedItems.Count == 0)
            {
                MessageBox.Show("请先选择要删除的字段", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            var selectedField = listViewFields.SelectedItems[0].Tag.ToString();
            
            var result = MessageBox.Show(
                $"确定要删除字段 '{selectedField}' 吗？\n\n这将同时删除所有文档中该字段的数据，此操作不可撤销！",
                "确认删除",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning);
                
            if (result != DialogResult.Yes)
                return;

            try
            {
                // 获取当前设置
                var settings = await MeilisearchUploader.Instance.GetIndexSettings(indexInfo.IndexName);
                var filterableAttributes = settings["filterableAttributes"] as JArray ?? new JArray();
                var sortableAttributes = settings["sortableAttributes"] as JArray ?? new JArray();
                var displayedAttributes = settings["displayedAttributes"] as JArray ?? new JArray();
                var searchableAttributes = settings["searchableAttributes"] as JArray ?? new JArray(); // 新增：获取searchableAttributes

                // 从各个设置中移除字段
                var newFilterableAttributes = new JArray(filterableAttributes.Where(x => x.ToString() != selectedField));
                var newSortableAttributes = new JArray(sortableAttributes.Where(x => x.ToString() != selectedField));
                var newDisplayedAttributes = new JArray(displayedAttributes.Where(x => x.ToString() != selectedField));
                var newSearchableAttributes = new JArray(searchableAttributes.Where(x => x.ToString() != selectedField)); // 新增：从searchableAttributes中移除字段

                // 更新索引设置
                var updateSettings = new JObject();
                updateSettings["filterableAttributes"] = newFilterableAttributes;
                updateSettings["sortableAttributes"] = newSortableAttributes;
                updateSettings["displayedAttributes"] = newDisplayedAttributes;
                updateSettings["searchableAttributes"] = newSearchableAttributes; // 新增：更新searchableAttributes

                await MeilisearchUploader.Instance.UpdateIndexSettings(indexInfo.IndexName, updateSettings);
                
                // 从文档中删除字段
                await RemoveFieldFromExistingDocuments(selectedField);
                
                MessageBox.Show("字段删除成功", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                LoadFields(); // 刷新显示
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除字段失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            LoadFields();
        }

        /// <summary>
        /// 为现有文档添加新字段的默认值
        /// </summary>
        /// <param name="fieldName">字段名</param>
        /// <param name="defaultValue">默认值</param>
        private async Task AddFieldToExistingDocuments(string fieldName, object defaultValue)
        {
            try
            {
                // 显示进度对话框
                var progressForm = new Form()
                {
                    Text = "更新文档",
                    Size = new Size(400, 150),
                    StartPosition = FormStartPosition.CenterParent,
                    FormBorderStyle = FormBorderStyle.FixedDialog,
                    MaximizeBox = false,
                    MinimizeBox = false
                };

                var progressBar = new ProgressBar()
                {
                    Dock = DockStyle.Top,
                    Style = ProgressBarStyle.Marquee
                };

                var label = new Label()
                {
                    Text = "正在更新现有文档，请稍候...",
                    Dock = DockStyle.Fill,
                    TextAlign = ContentAlignment.MiddleCenter
                };

                progressForm.Controls.Add(label);
                progressForm.Controls.Add(progressBar);
                progressForm.Show();

                // 获取所有文档（分批处理）
                const int batchSize = 1000;
                int offset = 0;
                int totalUpdated = 0;

                while (true)
                {
                    // 使用搜索API获取文档，因为GetDocuments可能有限制
                    var searchResult = await MeilisearchUploader.Instance.Search(
                        indexInfo.IndexName,
                        "",
                        batchSize,
                        offset,
                        "");

                    var hits = searchResult["hits"] as JArray;
                    if (hits == null || hits.Count == 0)
                    {
                        break; // 没有更多文档
                    }

                    // 更新这批文档
                    var updatedDocuments = new JArray();
                    foreach (JObject doc in hits)
                    {
                        // 如果文档中还没有这个字段，则添加
                        if (!doc.ContainsKey(fieldName))
                        {
                            doc[fieldName] = JToken.FromObject(defaultValue);
                            updatedDocuments.Add(doc);
                        }
                    }

                    // 如果有需要更新的文档，则批量更新
                    if (updatedDocuments.Count > 0)
                    {
                        await MeilisearchUploader.Instance.AddOrUpdateDocuments(updatedDocuments, indexInfo.IndexName);
                        totalUpdated += updatedDocuments.Count;
                    }

                    offset += batchSize;

                    // 如果返回的文档数少于批次大小，说明已经是最后一批
                    if (hits.Count < batchSize)
                    {
                        break;
                    }
                }

                progressForm.Close();

                MessageBox.Show(
                    $"成功为 {totalUpdated} 个文档添加了字段 '{fieldName}'。",
                    "更新完成",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    $"更新现有文档失败：{ex.Message}",
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 根据字段类型获取默认值
        /// </summary>
        /// <param name="fieldType">字段类型</param>
        /// <returns>默认值</returns>
        private object GetDefaultValueByType(string fieldType)
        {
            switch (fieldType?.ToLower())
            {
                case "string":
                    return "";
                case "number":
                    return 0;
                case "boolean":
                    return false;
                case "array":
                    return new JArray();
                case "object":
                    return new JObject();
                default:
                    return "";
            }
        }

        /// <summary>
        /// 从现有文档中删除指定字段
        /// </summary>
        /// <param name="fieldName">要删除的字段名</param>
        private async Task RemoveFieldFromExistingDocuments(string fieldName)
        {
            try
            {
                // 显示进度对话框
                var progressForm = new Form()
                {
                    Text = "删除字段",
                    Size = new Size(400, 150),
                    StartPosition = FormStartPosition.CenterParent,
                    FormBorderStyle = FormBorderStyle.FixedDialog,
                    MaximizeBox = false,
                    MinimizeBox = false
                };

                var progressBar = new ProgressBar()
                {
                    Dock = DockStyle.Top,
                    Style = ProgressBarStyle.Marquee
                };

                var label = new Label()
                {
                    Text = $"正在从文档中删除字段 '{fieldName}'，请稍候...",
                    Dock = DockStyle.Fill,
                    TextAlign = ContentAlignment.MiddleCenter
                };

                progressForm.Controls.Add(label);
                progressForm.Controls.Add(progressBar);
                progressForm.Show();
                Application.DoEvents(); // 确保界面更新

                // 获取所有文档（改进的分批处理）
                const int batchSize = 500; // 减小批次大小
                int totalUpdated = 0;
                int processedCount = 0;
                
                // 使用不同的方法获取所有文档
                bool hasMoreDocuments = true;
                string lastDocumentId = null;

                while (hasMoreDocuments)
                {
                    JArray hits;
                    
                    // 尝试使用不同的搜索策略
                    if (string.IsNullOrEmpty(lastDocumentId))
                    {
                        // 第一次搜索
                        var searchResult = await MeilisearchUploader.Instance.Search(
                            indexInfo.IndexName,
                            "",
                            batchSize,
                            0,
                            "");
                        hits = searchResult["hits"] as JArray;
                    }
                    else
                    {
                        // 后续搜索，使用过滤条件避免重复
                        var searchResult = await MeilisearchUploader.Instance.Search(
                            indexInfo.IndexName,
                            "",
                            batchSize,
                            0,
                            $"id > {lastDocumentId}"); // 假设有id字段
                        hits = searchResult["hits"] as JArray;
                    }

                    if (hits == null || hits.Count == 0)
                    {
                        hasMoreDocuments = false;
                        break;
                    }

                    // 更新这批文档
                    var updatedDocuments = new JArray();
                    foreach (JObject doc in hits)
                    {
                        processedCount++;
                        
                        // 记录最后一个文档的ID
                        if (doc.ContainsKey("id"))
                        {
                            lastDocumentId = doc["id"].ToString();
                        }

                        // 如果文档中包含这个字段，则删除
                        if (doc.ContainsKey(fieldName))
                        {
                            // 创建文档副本以避免修改原始对象
                            var docCopy = JObject.Parse(doc.ToString());
                            docCopy.Remove(fieldName);
                            updatedDocuments.Add(docCopy);
                        }
                    }

                    // 如果有需要更新的文档，则批量更新
                    if (updatedDocuments.Count > 0)
                    {
                        await MeilisearchUploader.Instance.AddOrUpdateDocuments(updatedDocuments, indexInfo.IndexName);
                        totalUpdated += updatedDocuments.Count;
                        
                        // 更新进度显示
                        label.Text = $"正在删除字段 '{fieldName}'... 已处理 {processedCount} 个文档，更新了 {totalUpdated} 个";
                        Application.DoEvents();
                    }

                    // 如果返回的文档数少于批次大小，说明已经是最后一批
                    if (hits.Count < batchSize)
                    {
                        hasMoreDocuments = false;
                    }
                    
                    // 添加小延迟避免过于频繁的请求
                    await Task.Delay(100);
                }

                progressForm.Close();

                MessageBox.Show(
                    $"处理完成！\n\n总共处理了 {processedCount} 个文档\n成功从 {totalUpdated} 个文档中删除了字段 '{fieldName}'。",
                    "删除完成",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    $"从文档中删除字段失败：{ex.Message}\n\n详细错误：{ex.StackTrace}",
                    "错误",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
    }

    // 添加字段对话框
    public partial class AddFieldDialog : Form
    {
        public string FieldName { get; private set; }
        public bool IsFilterable { get; private set; }
        public bool IsSortable { get; private set; }
        public string FieldType { get; private set; } // 新增字段类型属性

        private TextBox textBoxFieldName;
        private CheckBox checkBoxFilterable;
        private CheckBox checkBoxSortable;
        private ComboBox comboBoxFieldType; // 新增字段类型选择
        private Button buttonOK;
        private Button buttonCancel;

        public AddFieldDialog()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.textBoxFieldName = new TextBox();
            this.checkBoxFilterable = new CheckBox();
            this.checkBoxSortable = new CheckBox();
            this.comboBoxFieldType = new ComboBox(); // 新增
            this.buttonOK = new Button();
            this.buttonCancel = new Button();
            this.SuspendLayout();
            
            // textBoxFieldName
            this.textBoxFieldName.Location = new Point(100, 20);
            this.textBoxFieldName.Name = "textBoxFieldName";
            this.textBoxFieldName.Size = new Size(200, 23);
            this.textBoxFieldName.TabIndex = 0;
            
            // comboBoxFieldType - 新增字段类型选择
            this.comboBoxFieldType.DropDownStyle = ComboBoxStyle.DropDownList;
            this.comboBoxFieldType.Location = new Point(100, 50);
            this.comboBoxFieldType.Name = "comboBoxFieldType";
            this.comboBoxFieldType.Size = new Size(200, 23);
            this.comboBoxFieldType.TabIndex = 1;
            this.comboBoxFieldType.Items.AddRange(new object[] {
                "string",
                "number",
                "boolean",
                "array",
                "object"
            });
            this.comboBoxFieldType.SelectedIndex = 0; // 默认选择string
            
            // checkBoxFilterable
            this.checkBoxFilterable.AutoSize = true;
            this.checkBoxFilterable.Location = new Point(100, 90); // 调整位置
            this.checkBoxFilterable.Name = "checkBoxFilterable";
            this.checkBoxFilterable.Size = new Size(75, 21);
            this.checkBoxFilterable.TabIndex = 2;
            this.checkBoxFilterable.Text = "可过滤";
            this.checkBoxFilterable.UseVisualStyleBackColor = true;
            
            // checkBoxSortable
            this.checkBoxSortable.AutoSize = true;
            this.checkBoxSortable.Location = new Point(200, 90); // 调整位置
            this.checkBoxSortable.Name = "checkBoxSortable";
            this.checkBoxSortable.Size = new Size(75, 21);
            this.checkBoxSortable.TabIndex = 3;
            this.checkBoxSortable.Text = "可排序";
            this.checkBoxSortable.UseVisualStyleBackColor = true;
            
            // buttonOK
            this.buttonOK.DialogResult = DialogResult.OK;
            this.buttonOK.Location = new Point(100, 130); // 调整位置
            this.buttonOK.Name = "buttonOK";
            this.buttonOK.Size = new Size(75, 23);
            this.buttonOK.TabIndex = 4;
            this.buttonOK.Text = "确定";
            this.buttonOK.UseVisualStyleBackColor = true;
            this.buttonOK.Click += ButtonOK_Click;
            
            // buttonCancel
            this.buttonCancel.DialogResult = DialogResult.Cancel;
            this.buttonCancel.Location = new Point(200, 130); // 调整位置
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new Size(75, 23);
            this.buttonCancel.TabIndex = 5;
            this.buttonCancel.Text = "取消";
            this.buttonCancel.UseVisualStyleBackColor = true;
            
            // AddFieldDialog
            this.AcceptButton = this.buttonOK;
            this.AutoScaleDimensions = new SizeF(7F, 17F);
            this.AutoScaleMode = AutoScaleMode.Font;
            this.CancelButton = this.buttonCancel;
            this.ClientSize = new Size(350, 180); // 调整高度
            this.Controls.Add(this.buttonCancel);
            this.Controls.Add(this.buttonOK);
            this.Controls.Add(this.checkBoxSortable);
            this.Controls.Add(this.checkBoxFilterable);
            this.Controls.Add(this.comboBoxFieldType); // 新增
            this.Controls.Add(this.textBoxFieldName);
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "AddFieldDialog";
            this.StartPosition = FormStartPosition.CenterParent;
            this.Text = "添加字段";
            this.ResumeLayout(false);
            this.PerformLayout();
            
            // 添加标签
            var labelFieldName = new Label();
            labelFieldName.AutoSize = true;
            labelFieldName.Location = new Point(20, 23);
            labelFieldName.Name = "labelFieldName";
            labelFieldName.Size = new Size(56, 17);
            labelFieldName.TabIndex = 6;
            labelFieldName.Text = "字段名：";
            this.Controls.Add(labelFieldName);
            
            // 新增字段类型标签
            var labelFieldType = new Label();
            labelFieldType.AutoSize = true;
            labelFieldType.Location = new Point(20, 53);
            labelFieldType.Name = "labelFieldType";
            labelFieldType.Size = new Size(68, 17);
            labelFieldType.TabIndex = 7;
            labelFieldType.Text = "字段类型：";
            this.Controls.Add(labelFieldType);
        }

        private void ButtonOK_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(textBoxFieldName.Text))
            {
                MessageBox.Show("请输入字段名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            FieldName = textBoxFieldName.Text.Trim();
            IsFilterable = checkBoxFilterable.Checked;
            IsSortable = checkBoxSortable.Checked;
            FieldType = comboBoxFieldType.SelectedItem?.ToString() ?? "string"; // 新增
        }
    }
}
